using HelixToolkit.Wpf;
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Media3D;

namespace OptoSky.Common
{
    public class Wafer3D : ModelVisual3D
    {
        private readonly ModelVisual3D _visualChild;

        public Wafer3D()
        {
            _visualChild = new ModelVisual3D();
            Children.Add(_visualChild);

            var brush = new LinearGradientBrush { StartPoint = new Point(0, 0), EndPoint = new Point(0, 1) };
            brush.GradientStops.Add(new GradientStop(Colors.Red, 1.00));
            brush.GradientStops.Add(new GradientStop(Colors.Orange, 0.84));
            brush.GradientStops.Add(new GradientStop(Colors.Yellow, 0.67));
            brush.GradientStops.Add(new GradientStop(Colors.Green, 0.50));
            brush.GradientStops.Add(new GradientStop(Colors.Blue, 0.33));
            //brush.GradientStops.Add(new GradientStop(Colors.Indigo, 0.17));
            //brush.GradientStops.Add(new GradientStop(Colors.Violet, 0.00));
            SurfaceBrush = brush;

            
        }

        public Point3D[,] points;

        public Point3D[,] Points
        {
            get { return points; }
			
            set { points = value; 
			_visualChild.Content = CreateModel(); }
        }

        public Brush surfaceBrush;

        public Brush SurfaceBrush
        {
            get { return surfaceBrush; }
            set { surfaceBrush = value; }
        }

        public double MinZ = double.MaxValue;
        public double MaxZ = double.MinValue;

        private Model3D CreateModel()
        {
            var plotModel = new Model3DGroup();
            int rows = Points.GetUpperBound(0) + 1;
            int columns = Points.GetUpperBound(1) + 1;
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double z = Points[i, j].Z;
                    MaxZ = Math.Max(MaxZ, z);
                    MinZ = Math.Min(MinZ, z);
                }
            //var mid = (maxZ - minZ) / 2;
            var texcoords = new Point[rows, columns];
            for (int i = 0; i < rows; i++)
                for (int j = 0; j < columns; j++)
                {
                    double u = (Points[i, j].Z - MinZ) / (MaxZ - MinZ);
                    texcoords[i, j] = new Point(u, u);
                    //Points[i, j].Z = mid;
                }
            var surfaceMeshBuilder = new MeshBuilder();

            surfaceMeshBuilder.AddRectangularMesh(Points, texcoords);
            var surfaceModel = new GeometryModel3D(surfaceMeshBuilder.ToMesh(), MaterialHelper.CreateMaterial(SurfaceBrush, null, null, 1, 0));
            surfaceModel.BackMaterial = surfaceModel.Material;
            plotModel.Children.Add(surfaceModel);

            return plotModel;
        }
    }
}